package me.zhengjie.modules.web.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import me.zhengjie.config.enums.AgeTypeEnum;
import me.zhengjie.config.enums.ExamTypeEnum;
import me.zhengjie.modules.system.domain.ExamReportParams;
import me.zhengjie.modules.system.service.*;
import me.zhengjie.modules.system.service.dto.AdvertDto;
import me.zhengjie.modules.system.service.dto.AtmrDto;
import me.zhengjie.modules.system.service.dto.ExamInfoDto;
import me.zhengjie.modules.system.service.dto.ExamReportParamsDto;
import me.zhengjie.modules.utils.ResultToReportUtil;
import me.zhengjie.modules.web.domain.config.RichTextResp;
import me.zhengjie.modules.web.service.ICreateReportService;
import me.zhengjie.modules.web.service.config.IConfigService;
import me.zhengjie.repository.LogRepository;
import me.zhengjie.service.LogService;
import me.zhengjie.utils.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import reactor.util.function.Tuple4;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author CN-xianchengzhao
 * @description: TODO
 * @date 2021/11/21 20:55
 */
@Service
public class CreateReportServiceImpl implements ICreateReportService {

    private static final Logger log = LoggerFactory.getLogger(CreateReportServiceImpl.class);

    @Autowired
    ExamInfoService examInfoService;

    @Autowired
    AdvertService advertService;

    @Autowired
    LogService logService;

    @Autowired
    AtmrService atmrService;

    @Autowired
    ExamReportParamsService examReportParamsService;

    @Autowired
    IConfigService configService;

    public static void main(String[] args) {
        String s = "1224_1|1225_2|1232_5|1234_5|1244_5|1249_5|1227_5|1239_5|1243_5|1251_4|1230_4|1238_5|1246_5|1248_5|1231_5|1237_5|1241_5|1252_5|1226_5|1236_5|1242_5|1250_5|1229_5|1235_5|1240_5|1247_4|1228_5|1233_4|1245_5|1253_4";
        System.out.println(s.split("\\|").length);
        List<String> list = Splitter.on("|").splitToList(s);
        System.out.println(list.get(0));
        System.out.println(list.get(1));
        List<String> list1 = Splitter.on("_").splitToList(list.get(0));
        System.out.println(list1.get(1));
        //String singleGroup = getSingleGroup(s);
        //System.out.println(singleGroup);
    }

    /**
     * @param result
     * @param exam_content
     * @return
     */
    @Override
    public Map<String, Object> create(String wxId,Integer atmrId, String result, String exam_content) {
        AtmrDto atmrDto = atmrService.findById(atmrId);
        List<ExamInfoDto> examInfoDtoList = queryExamInfo(exam_content);
        result = sumScores(examInfoDtoList);
        Map<String, Object> model = new HashMap<>();
        model.put("ageType",atmrDto.getAgeType());
        if(AgeTypeEnum.CHILD.getCode().equals(atmrDto.getAgeType())){
            RichTextResp richTextResp = configService.getRichTextByType("richtext_type_zuo_you_li_lun");
            if(!ObjectUtils.isEmpty(richTextResp)){
                model.put("zuoYouLiLun",richTextResp.getContent());
            }
        }
        String[] results = result.split(",");
        float AFen = Float.parseFloat(results[0]);
        float TFen = Float.parseFloat(results[1]);
        float MFen = Float.parseFloat(results[2]);
        float RFen = Float.parseFloat(results[3]);
        String UpFen = getSingleGroup(examInfoDtoList);
        String singleGroupType = getSingleGroupType(UpFen);
        log.info("----------UpFen={},singleGroupType={}", UpFen, singleGroupType);
        if (singleGroupType.equalsIgnoreCase("A")){
            AFen+=5;
        }else if (singleGroupType.equalsIgnoreCase("T")){
            TFen+=5;
        }else if (singleGroupType.equalsIgnoreCase("M")){
            MFen+=5;
        }else if (singleGroupType.equalsIgnoreCase("R")){
            RFen+=5;
        }
        result = AFen+","+TFen+","+MFen+","+RFen;
        model.put("result",result);
        log.info("----------AFen={},TFen={},MFen={},RFen={}", AFen, TFen,MFen,RFen);
        model.putAll(ResultToReportUtil.getReport(result));
        model.put("syTezhi",ResultToReportUtil.calMaxResultType(result));
        model.put("cyTezhi",ResultToReportUtil.calCytz(result));
        Map<String, Object> parmas = new HashMap<>();
        parmas.put("result", result);
        parmas.put("content", exam_content);
        parmas.put("RFen", RFen);
        parmas.put("TFen", TFen);
        parmas.put("AFen", AFen);
        parmas.put("MFen", MFen);
        log.info("wxId={},RFen={},TFen={},TFen={},AFen={},MFen={}", wxId, RFen, TFen, AFen, MFen);
        logService.save(wxId, "WX", "CreateReportServiceImpl.create", JSONUtil.toJsonStr(parmas), "测试提交");

        if (!CollectionUtils.isEmpty(examInfoDtoList)) {
            List<String> heightScoreA = new ArrayList<>();//高分说明
            List<String> heightScoreT = new ArrayList<>();//高分说明
            List<String> heightScoreM = new ArrayList<>();//高分说明
            List<String> heightScoreR = new ArrayList<>();//高分说明
            int index = 0;
            for (ExamInfoDto examInfo : examInfoDtoList) {
                if(StringUtils.isEmpty(examInfo.getTitle()) || StringUtils.isEmpty(examInfo.getDescription())){
                    continue;
                }
                float testSc = examInfo.getTestScores();
                if ("1".equals(examInfo.getExamTypeId()))//单选题
                {
                    //UpFen += scores[choseIndex - 1];
                } else if ("6".equals(examInfo.getExamTypeId()))//A型题
                {
                    index = index + 1;
                    if (testSc > 3) {
                        String hsDesc = examInfo.getTitle() + ";" + examInfo.getDescription();
                        heightScoreA.add(hsDesc.replaceAll("null", ""));
                    }
                } else if ("4".equals(examInfo.getExamTypeId()))//T型题
                {
                    if (testSc > 3) {
                        String hsDesc = examInfo.getTitle() + ";" + examInfo.getDescription();
                        heightScoreT.add(hsDesc.replaceAll("null", ""));
                    }
                } else if ("5".equals(examInfo.getExamTypeId()))//M型题
                {
                    if (testSc > 3) {
                        String hsDesc = examInfo.getTitle() + ";" + examInfo.getDescription();
                        heightScoreM.add(hsDesc.replaceAll("null", ""));
                    }
                } else if ("7".equals(examInfo.getExamTypeId()))//R型题
                {
                    if (testSc > 3) {
                        String hsDesc = examInfo.getTitle() + ";" + examInfo.getDescription();
                        heightScoreR.add(hsDesc.replaceAll("null", ""));
                    }
                }
            }

            //查询系统广告
            List<AdvertDto> advertPd = advertService.queryAll(null);
            if (!CollectionUtils.isEmpty(advertPd)) {
                List<AdvertDto> advertList = advertPd.stream().filter(s -> Objects.nonNull(s.getStatus()) && Objects.nonNull(s.getType()) && s.getStatus().equals("0") && "0".equals(s.getType())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(advertList)) {
                    model.put("advertList", advertList);
                }
                List<AdvertDto> companyContentList = advertPd.stream().filter(s -> Objects.nonNull(s.getStatus()) && Objects.nonNull(s.getType()) && s.getStatus().equals("0") &&  "1".equals(s.getType())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(companyContentList)) {
                    StringBuffer companyString = new StringBuffer();
                    companyContentList.stream().forEach(s -> {
                        companyString.append(s.getContent());
                    });
                    model.put("companyContent", companyString.toString());
                }
            }

            setExtInfo(model,atmrDto.getAgeType());

            String sortStr = model.get("reportTezhi").toString();
            sortStr = sortStr.replaceAll("-", ",");
            String[] sortStrs = sortStr.split(",");
            List<String> heightScores = new ArrayList<String>();
            for (String sort : sortStrs) {
                if ("A".equals(sort)) {
                    for (String a : heightScoreA) {
                        heightScores.add(a);
                    }
                }
                if ("T".equals(sort)) {
                    for (String a : heightScoreT) {
                        heightScores.add(a);
                    }
                }
                if ("M".equals(sort)) {
                    for (String a : heightScoreM) {
                        heightScores.add(a);
                    }
                }
                if ("R".equals(sort)) {
                    for (String a : heightScoreR) {
                        heightScores.add(a);
                    }
                }
            }
            if(heightScores == null || heightScores.isEmpty() || heightScores.size() == 0)
            {
                heightScores.add("无明显显著特质");
            }
            model.put("heightScore", heightScores);
        }

        if ("11".equals(UpFen)) {
            model.put("qys", "A");
        } else if ("12".equals(UpFen)) {
            model.put("qys", "T");
        } else if ("21".equals(UpFen)) {
            model.put("qys", "M");
        } else if ("22".equals(UpFen)) {
            model.put("qys", "R");
        }else {
            model.put("qys", "A");
        }
        return model;
    }

    private void setExtInfo(Map<String,Object> model,String ageType){
        ExamReportParamsDto examReportParamsDto = examReportParamsService.findById("b_"+ ageType+"_"+model.get("resultPage"));
        if(ObjectUtils.isEmpty(examReportParamsDto)){
           return;
        }
        Map<String,Object> tempMap = JSONUtil.toBean(JSONUtil.toJsonStr(examReportParamsDto),Map.class);
        model.putAll(tempMap);
    }

    private String getSingleGroupType(String pointGroup){
        switch (pointGroup){
            case "11":
                return "A";
            case "12":
                return "T";
            case "21":
                return "M";
            case "22":
                return "R";
        }
        return StringUtils.EMPTY;
    }
    private static String getSingleGroup(List<ExamInfoDto> examInfoDtoList){
        if (CollectionUtils.isEmpty(examInfoDtoList)){
            return StringUtils.EMPTY;
        }
        List<ExamInfoDto> singleExamList = examInfoDtoList.stream().filter(s -> ExamTypeEnum.S.getCode().equals(s.getExamTypeId())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(singleExamList) || singleExamList.size() < 2){
            return StringUtils.EMPTY;
        }
        return singleExamList.get(0).getTestScores().intValue() + "" +singleExamList.get(1).getTestScores().intValue();
    }

    private List<ExamInfoDto> queryExamInfo(String exam_content){
        if (StringUtils.isBlank(exam_content)){
            return new ArrayList<>();
        }
        List<ExamInfoDto> contentList = new ArrayList<>();
        List<String> list = Splitter.on("|").splitToList(exam_content);
        for(String c : list){
            List<String> exam = Splitter.on("_").splitToList(c);
            ExamInfoDto examInfo = examInfoService.findById(Integer.valueOf(exam.get(0)));
            String[] scores = examInfo.getScore().split(";");
            int choseIndex = Integer.parseInt(exam.get(1))-1;
            float num = Float.parseFloat(scores[choseIndex]) ;
            examInfo.setTestScores(num);
            examInfo.setChoseIndex(Integer.parseInt(exam.get(1)));
            contentList.add(examInfo);
        }
        return contentList;
    }

    private String sumScores(List<ExamInfoDto> contentList){
        Map<String,Float> map = MapUtil.newHashMap();
        map.put("A",0f);
        map.put("T",0f);
        map.put("M",0f);
        map.put("R",0f);
        if (CollectionUtils.isEmpty(contentList)){
            return null;
        }
        Map<String,List<ExamInfoDto>> subMap = contentList.stream().collect(Collectors.groupingBy(ExamInfoDto :: getExamTypeId));
        Set<Map.Entry<String, List<ExamInfoDto>>> set = subMap.entrySet();
        for(Map.Entry<String, List<ExamInfoDto>> entry : set){
            if("1".equals(entry.getKey()) || "2".equals(entry.getKey())){
                continue;
            }
            List<ExamInfoDto> atmrList = entry.getValue();
            if(CollectionUtils.isEmpty(atmrList)){
                continue;
            }
            String type = entry.getKey();
            ExamTypeEnum examTypeEnum = ExamTypeEnum.get(type);

            Map<String,List<ExamInfoDto>> groupMap = atmrList.stream().collect(Collectors.groupingBy(ExamInfoDto :: getGroupCode));
            Set<Map.Entry<String, List<ExamInfoDto>>> groupSet = groupMap.entrySet();
            for(Map.Entry<String, List<ExamInfoDto>> groupEntry : groupSet){
                List<ExamInfoDto> groupExamList = groupEntry.getValue();
                long count = groupExamList.stream().count();
                Double sc = groupExamList.stream().mapToDouble(ExamInfoDto :: getTestScores).sum();
                Double per = sc/count;
                map.put(examTypeEnum.getAtmr(),map.get(examTypeEnum.getAtmr())+per.floatValue());
            }
        }

        return StringUtils.join(new Float[]{map.get("A"),map.get("T"),map.get("M"),map.get("R")},",");
    }
    private Pair<Integer,Integer> getScore(List<ExamInfoDto> list){
        if(CollectionUtils.isEmpty(list)){
            return Pair.of(0,0);
        }
        Long count = list.stream().filter(s -> ExamTypeEnum.A.getCode().equals(s.getExamTypeId())).count();
        return Pair.of(5 * count.intValue() / 3,10 * count.intValue() / 3);
    }
}
